package com.sqx.modules.app.service.impl;


import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.getui.push.v2.sdk.ApiHelper;
import com.getui.push.v2.sdk.GtApiConfiguration;
import com.getui.push.v2.sdk.api.PushApi;
import com.getui.push.v2.sdk.common.ApiResult;
import com.getui.push.v2.sdk.dto.req.Audience;
import com.getui.push.v2.sdk.dto.req.message.PushDTO;
import com.getui.push.v2.sdk.dto.req.message.PushMessage;
import com.getui.push.v2.sdk.dto.req.message.android.GTNotification;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.jyt.baseUtil.jedis.bean.RedisCache;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.RedisUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.EmailCodeDao;
import com.sqx.modules.app.dao.MsgDao;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.entity.*;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.app.service.UserVipService;
import com.sqx.modules.app.utils.JwtUtils;
import com.sqx.modules.app.utils.UserConstantInterface;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.file.utils.Md5Utils;
import com.sqx.modules.invite.service.InviteService;
import com.sqx.modules.pay.dao.UserDramaPointDao;
import com.sqx.modules.pay.entity.UserDramaPoint;
import com.sqx.modules.utils.HttpClientUtil;
import com.sqx.modules.utils.InvitationCodeUtil;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import weixin.popular.api.SnsAPI;
import weixin.popular.util.JsonUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.sqx.modules.app.utils.CustomerSmsUtils.send;

/**
 * 用户
 *
 * @author fang
 * @date 2021/2/27
 */

@Service("userService")
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    @Autowired
    private CommonInfoService commonInfoService;
    @Autowired
    private MsgDao msgDao;
    @Autowired
    private JwtUtils jwtUtils;
    private int number = 1;
	@Autowired
	private InviteService inviteService;
	@Autowired
    private UserMoneyService userMoneyService;
	@Autowired
    private UserVipService userVipService;

    @Value("${spring.mail.username}")
    private String sender;

    @Value("${spring.mail.nickname}")
    private String nickname;

    @Autowired
    private JavaMailSender javaMailSender;
    @Autowired
    private EmailCodeDao emailCodeDao;

    @Autowired
    private Ip2regionSearcher ip2regionSearcher;
    @Autowired
    private UserDramaPointDao userDramaPointDao;

    @Override
    public UserEntity queryByPhone(String phone) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("phone", phone));
    }

    @Override
    public UserEntity queryByOpenId(String openId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("open_id", openId));
    }

    @Override
    public UserEntity queryByWxId(String wxId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("wx_id", wxId));
    }

    @Override
    public UserEntity queryByWxOpenId(String openId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("wx_open_id", openId));
    }

    @Override
    public UserEntity queryByAppleId(String appleId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("apple_id", appleId));
    }

    @Override
    public UserEntity queryByUserId(Long userId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("user_id", userId));
    }

    @Override
    public UserEntity queryByInvitationCode(String invitationCode){
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("invitation_code", invitationCode));
    }

    @Override
    public Result updatePhone(String phone, String msg, Long userId) {
        Msg msg1 = msgDao.findByPhoneAndCode(phone, msg);
        //校验短信验证码
        if (msg1 != null) {
            msgDao.deleteById(msg1.getId());
            UserEntity userInfo = queryByPhone(phone);
            if (userInfo != null) {
                return Result.error("手机号已经被其他账号绑定");
            } else {
                UserEntity one = baseMapper.selectById(userId);
                one.setPhone(phone);
                baseMapper.updateById(one);
                return Result.success();
            }
        }
        return Result.error("验证码不正确");
    }

    @Override
    public Result iosRegister(String appleId) {
        if (StringUtils.isEmpty(appleId)) {
            return Result.error("账号信息获取失败，请退出重试！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        // 根据返回的user实体类，判断用户是否是新用户，不是的话，更新最新登录时间，是的话，将用户信息存到数据库
        UserEntity userInfo = queryByAppleId(appleId);
        if (userInfo != null) {
            if (userInfo.getStatus().equals(2)) {
                return Result.error("账号已被封禁，请联系客服处理！");
            }
            userInfo.setUpdateTime(date);
            baseMapper.updateById(userInfo);
            //返回用户信息
            UserEntity user = queryByAppleId(appleId);
            return getResult(user);
        } else {
            return Result.error(-200, "请先绑定手机号账号！");
        }
    }

    @Override
    public Result wxLogin(String code) {
        try {
            String appid = commonInfoService.findOne(45).getValue();
            String secret = commonInfoService.findOne(46).getValue();
            // 配置请求参数
            Map<String, String> param = new HashMap<>();
            param.put("appid", appid);
            param.put("secret", secret);
            param.put("js_code", code);
            param.put("grant_type", UserConstantInterface.WX_LOGIN_GRANT_TYPE);
            param.put("scope", "snsapi_userinfo");
            // 发送请求
            String wxResult = HttpClientUtil.doGet(UserConstantInterface.WX_LOGIN_URL, param);
            log.info(wxResult);
            JSONObject jsonObject = JSONObject.parseObject(wxResult);
            // 获取参数返回的
            String session_key = jsonObject.get("session_key").toString();
            String open_id = jsonObject.get("openid").toString();
            UserEntity userEntity = queryByOpenId(open_id);
            Map<String, String> map = new HashMap<>();
            // 封装返回小程序
            map.put("session_key", session_key);
            map.put("open_id", open_id);
            if (jsonObject.get("unionid") != null) {
                String unionid = jsonObject.get("unionid").toString();
                map.put("unionid", unionid);
            } else {
                map.put("unionid", "-1");
            }
            String value = commonInfoService.findOne(237).getValue();
            if("是".equals(value)){
                if (userEntity == null || StringUtils.isEmpty(userEntity.getPhone())) {
                    map.put("flag", "1");
                } else {
                    map.put("flag", "2");
                }
            }else{
                map.put("flag", "2");
            }
            return Result.success("登陆成功").put("data", map);
        } catch (Exception e) {
            System.err.println(e.toString());
            return Result.success("登录失败！");
        }
    }


    @Override
    public Result wxRegister(UserEntity userInfo1) {
        if (StringUtils.isEmpty(userInfo1.getOpenId())) {
            return Result.error("账号信息获取失败，请退出重试！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        // 根据返回的user实体类，判断用户是否是新用户，不是的话，更新最新登录时间，是的话，将用户信息存到数据库
        UserEntity userInfo = queryByOpenId(userInfo1.getOpenId());
        if (userInfo != null) {
            if (userInfo.getStatus().equals(2)) {
                return Result.error("账号已被封禁，请联系客服处理！");
            }
            /*if (StringUtils.isNotEmpty(userInfo1.getUserName())) {
                userInfo.setUserName(userInfo1.getUserName());
            }
            if (StringUtils.isNotEmpty(userInfo1.getAvatar())) {
                userInfo.setAvatar(userInfo1.getAvatar());
            }
            if (StringUtils.isNotEmpty(userInfo1.getPhone())) {
                userInfo.setPhone(userInfo1.getPhone());
            }*/
            userInfo.setUpdateTime(date);
            baseMapper.updateById(userInfo);
        } else {
            //判断是否在app登陆过  手机号是否有账号
            UserEntity userByMobile = queryByPhone(userInfo1.getPhone());
            if (userByMobile != null) {
                //有账号则绑定账号
                userByMobile.setOpenId(userInfo1.getOpenId());
                baseMapper.updateById(userByMobile);
                if (userByMobile.getStatus().equals(2)) {
                    return Result.error("账号已被封禁，请联系客服处理！");
                }
            } else {
                if(StringUtils.isEmpty(userInfo1.getInviterCode())){
                    userInfo1.setInviterCode(commonInfoService.findOne(88).getValue());
                }
                UserEntity userEntity = queryByInvitationCode(userInfo1.getInviterCode());
                //没有则生成新账号
                userInfo1.setCreateTime(date);
                userInfo1.setPlatform("小程序");
                userInfo1.setStatus(1);
                userInfo1.setPassword(DigestUtils.sha256Hex(userInfo1.getPhone()));
                userInfo1.setRate(new BigDecimal(commonInfoService.findOne(80).getValue()));
                baseMapper.insert(userInfo1);
                userInfo1.setInvitationCode(InvitationCodeUtil.toSerialCode(userInfo1.getUserId()));
                baseMapper.updateById(userInfo1);
                if(userEntity!=null){
                    inviteService.saveBody(userInfo1.getUserId(),userEntity);
                }
//                userMoneyService.selectUserMoneyByUserId(userInfo1.getUserId());
            }
        }
        //返回用户信息
        UserEntity user = queryByOpenId(userInfo1.getOpenId());
        return getResult(user);
    }


    @Override
    public Result wxBindMobile(String phone, String code, String wxOpenId, String token, String platform, Integer sysPhone) {
        Msg byPhoneAndCode = msgDao.findByPhoneAndCode(phone, code);
        if (byPhoneAndCode == null) {
            return Result.error("验证码错误");
        }
        msgDao.deleteById(byPhoneAndCode.getId());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());
        UserEntity userInfo = queryByPhone(phone);
        if (userInfo != null) {
            if (StringUtils.isNotEmpty(userInfo.getWxOpenId())) {
                return Result.error("当前手机号已经被其他微信绑定");
            }
            //小程序登陆过
            userInfo.setWxOpenId(wxOpenId);
            String s = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + wxOpenId);
            AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
            if (user != null && user.getNickname() != null) {
                if (user.getHeadimgurl() != null) {
                    userInfo.setAvatar(user.getHeadimgurl());
                }
                userInfo.setSex(user.getSex());
                if (user.getNickname() != null) {
                    userInfo.setUserName(user.getNickname().replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
                }
            }
            baseMapper.updateById(userInfo);
        } else {
            //小程序没有登陆过
            userInfo = new UserEntity();
            String s = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + wxOpenId);
            AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
            if (user != null && user.getNickname() != null) {
                if (user.getHeadimgurl() != null) {
                    userInfo.setAvatar(user.getHeadimgurl());
                }
                userInfo.setSex(user.getSex());
                if (user.getNickname() != null) {
                    userInfo.setUserName(user.getNickname().replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
                }
            }
            userInfo.setWxOpenId(wxOpenId);
            userInfo.setPhone(phone);
            userInfo.setPlatform(platform);
            userInfo.setCreateTime(time);
            userInfo.setSysPhone(sysPhone);
            userInfo.setStatus(1);
            userInfo.setUpdateTime(time);
            userInfo.setRate(new BigDecimal(commonInfoService.findOne(80).getValue()));
            baseMapper.insert(userInfo);
        }
        UserEntity userEntity = queryByWxOpenId(userInfo.getWxOpenId());
        return getResult(userEntity);
    }

    @Override
    public Result iosBindMobile(String phone, String code, String appleId, String platform, Integer sysPhone) {
        Msg byPhoneAndCode = msgDao.findByPhoneAndCode(phone, code);
        if (byPhoneAndCode == null) {
            return Result.error("验证码错误");
        }
        msgDao.deleteById(byPhoneAndCode.getId());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());
        UserEntity userInfo = queryByPhone(phone);
        if (userInfo != null) {
            if (StringUtils.isNotEmpty(userInfo.getAppleId())) {
                return Result.error("当前手机号已经被其他苹果绑定");
            }
            userInfo.setAppleId(appleId);
            userInfo.setUpdateTime(simpleDateFormat.format(new Date()));
            baseMapper.updateById(userInfo);
        } else {
            userInfo = new UserEntity();
            userInfo.setSex(0);
            userInfo.setUserName(phone.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
            userInfo.setPhone(phone);
            userInfo.setPlatform(platform);
            userInfo.setCreateTime(time);
            userInfo.setSysPhone(sysPhone);
            userInfo.setStatus(1);
            userInfo.setUpdateTime(time);
            userInfo.setRate(new BigDecimal(commonInfoService.findOne(80).getValue()));
            baseMapper.insert(userInfo);
        }
        UserEntity userEntity = queryByAppleId(userInfo.getAppleId());
        return getResult(userEntity);
    }


    @Override
    public Result wxAppLogin(String wxOpenId, String token) {
        UserEntity userEntity = queryByWxOpenId(wxOpenId);
        if (userEntity != null) {
            if (userEntity.getStatus().equals(2)) {
                return Result.error("账号已被禁用，请联系客服处理！");
            }
            String s = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + wxOpenId);
            AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
            if (user != null && user.getNickname() != null) {
                if (user.getHeadimgurl() != null) {
                    userEntity.setAvatar(user.getHeadimgurl());
                }
                userEntity.setSex(user.getSex());
                if (user.getNickname() != null) {
                    userEntity.setUserName(user.getNickname().replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
                }
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            userEntity.setUpdateTime(sdf.format(new Date()));
            baseMapper.updateById(userEntity);
            return getResult(userEntity);
        } else {
            return Result.error(-200, "请先绑定手机号账号！");
        }
    }



    @Override
    public Result registerCode(String countryCode,String phone, String msg, String platform, Integer sysPhone,String password,String inviterCode,String wxId) {
        //校验手机号是否存在
        System.out.println("countryCode="+countryCode);
        LambdaQueryWrapper<UserEntity> userEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userEntityLambdaQueryWrapper.eq(UserEntity::getPhone, phone);
        userEntityLambdaQueryWrapper.eq(UserEntity::getCountryCode, countryCode);
        UserEntity userInfo = baseMapper.selectOne(userEntityLambdaQueryWrapper);
        System.out.println("userInfo="+userInfo);
//        UserEntity userInfo = queryByPhone(phone);
        if (userInfo != null) {//登录
            if(StringUtils.isNotEmpty(password)){
                //密码登录
                if(!userInfo.getPassword().equals(DigestUtils.sha256Hex(password))){
                    return Result.error("账号或密码不正确！");
                }
            }else if(StringUtils.isNotEmpty(msg)){
                //验证码登录
                Msg msg1 = msgDao.findByPhoneAndCode(phone, msg);
                if(msg1==null){
                    return Result.error("验证码不正确！");
                }
                msgDao.deleteById(msg1.getId());
            }else{
                return Result.error("登录失败，请刷新页面重试！");
            }
            if (userInfo.getStatus().equals(2)) {
                return Result.error("账号已被禁用，请联系客服处理！");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if(StringUtils.isNotEmpty(wxId) && StringUtils.isNotEmpty(userInfo.getWxId()) && !wxId.equals(userInfo.getWxId())){
                return Result.error("当前手机号已经绑定过了，请更换其他手机号！");
            }
            if(StringUtils.isNotEmpty(wxId)){
                userInfo.setWxId(wxId);
            }
            userInfo.setUpdateTime(sdf.format(new Date()));
            baseMapper.updateById(userInfo);
            return getResult(userInfo);
        } else {//注册
            Msg msg1 = null;
            if(!password.equals("duanju123")){//密码为duanju123时不需要验证码
                if(StringUtils.isEmpty(msg)){
                    return Result.error("验证码不能为空！");
                }
                msg1 = msgDao.findByPhoneAndCode(phone, msg);
                if(msg1==null){
                    return Result.error("验证码不正确！");
                }
            }

            userInfo = new UserEntity();
            UserEntity userEntity=null;
            if(StringUtils.isNotEmpty(inviterCode)){
                userEntity = queryByInvitationCode(inviterCode);
                if(userEntity==null){
                    return Result.error("邀请码不正确！");
                }
            }else{
                userInfo.setInviterCode(commonInfoService.findOne(88).getValue());
                userEntity = queryByInvitationCode(userInfo.getInviterCode());
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = simpleDateFormat.format(new Date());
            if(StringUtils.isNotEmpty(wxId)){
                userInfo.setWxId(wxId);
            }
            userInfo.setPhone(phone);
            userInfo.setCountryCode(countryCode);
            userInfo.setUserName(phone.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
            userInfo.setPlatform(platform);
            userInfo.setCreateTime(time);
            userInfo.setSysPhone(sysPhone);
            userInfo.setPassword(DigestUtils.sha256Hex(password));
            userInfo.setStatus(1);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            userInfo.setUpdateTime(sdf.format(new Date()));
            userInfo.setRate(new BigDecimal(commonInfoService.findOne(80).getValue()));
            baseMapper.insert(userInfo);
            userInfo.setInvitationCode(InvitationCodeUtil.toSerialCode(userInfo.getUserId()));
            baseMapper.updateById(userInfo);
            if (msg1!=null)msgDao.deleteById(msg1.getId());//密码为duanju123时不需要验证码
            if(userEntity!=null){
                inviteService.saveBody(userInfo.getUserId(),userEntity);
            }
            return getResult(userInfo);
        }
    }


    @Override
    public Result bindWxOpenPhone(Long userId, String phone, String msg) {
        Msg byPhoneAndCode = msgDao.findByPhoneAndCode(phone, msg);
        if (byPhoneAndCode == null) {
            return Result.error("验证码错误");
        }
        msgDao.deleteById(byPhoneAndCode.getId());
        UserEntity userEntity = queryByPhone(phone);
        if (userEntity != null) {
            return Result.error("当前手机号已经绑定过了，请直接登录！");
        }
        UserEntity byId = baseMapper.selectById(userId);
        byId.setPhone(phone);
        baseMapper.updateById(byId);
        return Result.success();
    }

    @Override
    public Result forgetPwd(String pwd, String phone, String msg) {
        try {
            Msg byPhoneAndCode = msgDao.findByPhoneAndCode(phone, msg);
            //校验短信验证码
            if (byPhoneAndCode == null) {
                return Result.error("验证码不正确");
            }
            UserEntity userByPhone = queryByPhone(phone);
            userByPhone.setPassword(DigestUtils.sha256Hex(pwd));
            msgDao.deleteById(byPhoneAndCode.getId());
            baseMapper.updateById(userByPhone);
            return Result.success();
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("服务器内部错误");
        }
    }




    @Override
    public Result login(String phone, String pwd) {
        UserEntity userEntity = queryByPhone(phone);
        if (userEntity == null) {
            return Result.error("手机号未注册！");
        }
        if (!userEntity.getPassword().equals(DigestUtils.sha256Hex(pwd))) {
            return Result.error("密码不正确！");
        }
        if (userEntity.getStatus().equals(2)) {
            return Result.error("账号已被禁用，请联系客服处理！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        userEntity.setUpdateTime(sdf.format(new Date()));
        baseMapper.updateById(userEntity);
        return getResult(userEntity);
    }


    @Override
    public Result getResult(UserEntity user) {
        //生成token
        String token = jwtUtils.generateToken(user.getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());
        map.put("user", user);
        return Result.success(map);
    }


    @Override
    public Result sendMsg(String phone, String state) {
        int code = (int) ((Math.random() * 9 + 1) * 100000);
        System.out.println("sendMsg code is " + code);
        SmsSingleSenderResult result = null;
        if ("bindWx".equals(state)) {
            UserEntity userByPhone = queryByPhone(phone);
            if (userByPhone != null && StringUtils.isNotEmpty(userByPhone.getWxOpenId())) {
                return Result.error("当前手机号已被其他微信账号绑定");
            }
        } else if ("bindIos".equals(state)) {
            UserEntity userByPhone = queryByPhone(phone);
            if (userByPhone != null && StringUtils.isNotEmpty(userByPhone.getAppleId())) {
                return Result.error("当前手机号已被其他苹果账号绑定");
            }
        }else if("login".equals(state)){
            UserEntity userByPhone = queryByPhone(phone);
            if(userByPhone!=null){
                return Result.error("当前手机号已注册！");
            }
        }else if("forget".equals(state)){
            UserEntity userByPhone = queryByPhone(phone);
            if(userByPhone==null){
                return Result.error("手机号未注册！");
            }
        }
        Msg msg = new Msg();
        msg.setCode(String.valueOf(code));
        msg.setPhone(phone);
        msgDao.insert(msg);
        return send(phone,code);
//        CommonInfo three = commonInfoService.findOne(79);
////        默认使用腾讯云
//        if (three == null || "1".equals(three.getValue())) {
//            //腾讯云短信发送
//            return sendMsgTencent(phone, state, code);
//        } else if("2".equals(three.getValue())){
//            //阿里云短信发送
//            return sendMsgAlibaba(phone, state,code);
//        }else{
//            return sendMsgDXB(phone,state,code);
//        }
    }


    private Result sendMsgAlibaba(String phone,String state, int code) {

        CommonInfo three = commonInfoService.findOne(85);
        String accessKeyId = three.getValue();
        CommonInfo four = commonInfoService.findOne(86);
        String accessSecret = four.getValue();
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessSecret);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonInfo name = commonInfoService.findOne(81);
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", name.getValue());
        String value;
        switch (state) {
            case "login":
                value=commonInfoService.findOne(82).getValue();
                break;
            case "forget":
                value=commonInfoService.findOne(83).getValue();
                break;
            case "bindWx":
                value=commonInfoService.findOne(84).getValue();
                break;
            case "bindIos":
                value=commonInfoService.findOne(84).getValue();
                break;
            default:
                value=commonInfoService.findOne(82).getValue();
                break;
        }
        request.putQueryParameter("TemplateCode", value);
        request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
        try {
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            String data = response.getData();
            JSONObject jsonObject = JSON.parseObject(data);
            if ("OK".equals(jsonObject.get("Code"))) {
                Msg byPhone = msgDao.findByPhone(phone);
                if (byPhone != null) {
                    byPhone.setCode(String.valueOf(code));
                    byPhone.setPhone(phone);
                    msgDao.updateById(byPhone);
                } else {
                    Msg msg = new Msg();
                    msg.setCode(String.valueOf(code));
                    msg.setPhone(phone);
                    msgDao.insert(msg);
                }
                UserEntity userByPhone = queryByPhone(phone);
                if (userByPhone != null) {
                    return Result.success("login");
                } else {
                    return Result.success("register");
                }
            } else {
                if (jsonObject.get("Message").toString().contains("分钟")) {
                    return Result.error("短信发送过于频繁，请一分钟后再试！");
                } else if (jsonObject.get("Message").toString().contains("小时")) {
                    return Result.error("短信发送过于频繁，请一小时后再试！");
                } else if (jsonObject.get("Message").toString().contains("天")) {
                    return Result.error("短信发送过于频繁，请明天再试！");
                }
                log.info(jsonObject.get("Message").toString());
                return Result.error("短信发送失败！");
            }
        } catch (ClientException | com.aliyuncs.exceptions.ClientException e) {
            e.printStackTrace();
        }
        return Result.error("验证码发送失败");
    }


    private Result userSendMsg(String phone,int code) {
        try {
            // 创建 URL 对象
            URL url = new URL("https://enjoymov.co/prod-api/kstbCore/sms/send");

            // 打开连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // 设置请求方法为 POST
            connection.setRequestMethod("POST");

            // 允许输出
            connection.setDoOutput(true);

            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            // 构建请求体
            String urlParameters = "uid=23410&pw=B0D3E4A8&mb="+phone+"&ms="+"【九州TV】 验证码为"+code+"，请勿与他人分享。"+"&ex=77";

            System.out.println(urlParameters);
            // 发送请求
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = urlParameters.getBytes("utf-8");
                os.write(input, 0, input.length);
            }

            // 获取响应码
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);

            // 断开连接
            connection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
            return Result.success("验证码发送失败");
        }
        Msg msg = new Msg();
        msg.setPhone(phone);
        msg.setCode(String.valueOf(code));
        return Result.success("验证码发送成功");
    }

    private Result sendMsgTencent(String phone, String state, int code) {
        SmsSingleSenderResult result = null;

        CommonInfo three = commonInfoService.findOne(31);
        String clientId = three.getValue();
        CommonInfo four = commonInfoService.findOne(32);
        String clientSecret = four.getValue();
        try {
            String secretId = commonInfoService.findOne(240).getValue();
            String secretKey = commonInfoService.findOne(241).getValue();
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(secretId, secretKey);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("sms.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            SmsClient client = new SmsClient(cred, "ap-beijing", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            SendSmsRequest req = new SendSmsRequest();
            String[] phoneNumberSet1 = {phone};
            req.setPhoneNumberSet(phoneNumberSet1);

            req.setSmsSdkAppId(clientId);
            CommonInfo one = commonInfoService.findOne(81);
            req.setSignName(one.getValue());
            switch (state) {
                case "register":
                    req.setTemplateId(commonInfoService.findOne(242).getValue());
                    break;
                case "forget":
                    req.setTemplateId(commonInfoService.findOne(243).getValue());
                    break;
                case "bind":
                    req.setTemplateId(commonInfoService.findOne(244).getValue());
                    break;
                default:
                    req.setTemplateId(commonInfoService.findOne(242).getValue());
                    break;
            }
            String[] templateParamSet1 = {String.valueOf(code)};
            req.setTemplateParamSet(templateParamSet1);

            // 返回的resp是一个SendSmsResponse的实例，与请求对象对应
            SendSmsResponse resp = client.SendSms(req);
            // 输出json格式的字符串回包
            JSONObject jsonObject = JSONObject.parseObject(SendSmsResponse.toJsonString(resp));
            JSONArray sendStatusSet = jsonObject.getJSONArray("SendStatusSet");
            JSONObject jsonObject1 = sendStatusSet.getJSONObject(0);
            if ("Ok".equals(jsonObject1.getString("Code"))) {
                Msg byPhone = msgDao.findByPhone(phone);
                if (byPhone != null) {
                    byPhone.setCode(String.valueOf(code));
                    byPhone.setPhone(phone);
                    msgDao.updateById(byPhone);
                } else {
                    Msg msg = new Msg();
                    msg.setCode(String.valueOf(code));
                    msg.setPhone(phone);
                    msgDao.insert(msg);
                }
                UserEntity userByPhone = queryByPhone(phone);
                if (userByPhone != null) {
                    return Result.success("login");
                } else {
                    return Result.success("register");
                }
            }
        } catch (TencentCloudSDKException e) {
            System.out.println(e.toString());
        }
        return Result.error("验证码发送失败");
    }


    private Result sendMsgDXB(String phone, String state, int code) {
        CommonInfo three = commonInfoService.findOne(238);
        CommonInfo four = commonInfoService.findOne(239);
        CommonInfo name = commonInfoService.findOne(81);
        String testUsername = three.getValue(); //在短信宝注册的用户名
        String testPassword = four.getValue(); //在短信宝注册的密码
        String value="";
        switch (state) {
            case "register":
                value = "【" + name.getValue() + "】验证码: " + code + "，此验证码可用于登录或注册，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            case "forget":
                value = "【" + name.getValue() + "】验证码: " + code + "，您正在执行找回密码操作，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            case "bind":
                value = "【" + name.getValue() + "】验证码: " + code + "，您正在执行绑定手机号操作，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            default:
                value = "【" + name.getValue() + "】验证码: " + code + "，此验证码可用于登录或注册，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
        }
        StringBuilder httpArg = new StringBuilder();
        httpArg.append("u=").append(testUsername).append("&");
        httpArg.append("p=").append(Md5Utils.md5s(testPassword)).append("&");
        httpArg.append("m=").append(phone).append("&");
        httpArg.append("c=").append(Md5Utils.encodeUrlString(value, "UTF-8"));
        String result = Md5Utils.request("https://api.smsbao.com/sms", httpArg.toString());
        log.error("短信包返回值："+result);
        if ("0".equals(result)) {
            Msg byPhone = msgDao.findByPhone(phone);
            if (byPhone != null) {
                byPhone.setCode(String.valueOf(code));
                byPhone.setPhone(phone);
                msgDao.updateById(byPhone);
            } else {
                Msg msg = new Msg();
                msg.setCode(String.valueOf(code));
                msg.setPhone(phone);
                msgDao.insert(msg);
            }
            UserEntity userByPhone = queryByPhone(phone);
            if (userByPhone != null) {
                return Result.success("login");
            } else {
                return Result.success("register");
            }
        } else {
//            return ResultUtil.error(6, result.errMsg);
            if("30".equals(result)){
                return Result.error( "错误密码");
            }else if("40".equals(result)){
                return Result.error( "账号不存在");
            }else if("41".equals(result)){
                return Result.error( "余额不足");
            }else if("43".equals(result)){
                return Result.error( "IP地址限制");
            }else if("50".equals(result)){
                return Result.error( "内容含有敏感词");
            }else if("51".equals(result)){
                return Result.error( "手机号码不正确");
            }
        }

        return Result.error("验证码发送失败");
    }


    @Override
    public Result getOpenId(String code, Long userId) {
        try {
            //微信appid
            CommonInfo one = commonInfoService.findOne(5);
            //微信秘钥
            CommonInfo two = commonInfoService.findOne(21);
            String openid = SnsAPI.oauth2AccessToken(one.getValue(), two.getValue(), code).getOpenid();
            if (StringUtils.isNotEmpty(openid)) {
                UserEntity userEntity = new UserEntity();
                userEntity.setUserId(userId);
                userEntity.setWxId(openid);
                baseMapper.updateById(userEntity);
                return Result.success().put("data", openid);
            }
            return Result.error("获取失败");
        } catch (Exception e) {
            log.error("GET_OPENID_FAIL");
            return Result.error("获取失败,出错了！");
        }
    }

    @Override
    public UserEntity selectUserById(Long userId) {
        UserEntity userEntity = baseMapper.selectById(userId);
        if(userEntity!=null){
            UserVip userVip = userVipService.selectUserVipByUserId(userId);
            if(userVip!=null){
                userEntity.setMember(userVip.getIsVip());
                userEntity.setEndTime(userVip.getEndTime());
            }
            LambdaQueryWrapper<UserDramaPoint> userDramaPointLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userDramaPointLambdaQueryWrapper.eq(UserDramaPoint::getUserId,userId);
            UserDramaPoint userDramaPoint = userDramaPointDao.selectOne(userDramaPointLambdaQueryWrapper);
            if(userDramaPoint!=null){
                userEntity.setDramaPointBalance(userDramaPoint.getBalance());
            }else {
                UserDramaPoint dramaPoint = new UserDramaPoint();
                dramaPoint.setUserId(userId.intValue());
                dramaPoint.setBalance(new BigDecimal(0));
                userDramaPointDao.insert(dramaPoint);
                userEntity.setDramaPointBalance(dramaPoint.getBalance());
            }
        }
        return userEntity;
    }


    @Override
    public PageUtils selectUserPage(Integer page, Integer limit, String search, Integer sex, String platform,
                                    String sysPhone, Integer status,Integer member,String inviterCode,String userName) {
        Page<UserEntity> pages = new Page<>(page, limit);
        return new PageUtils(baseMapper.selectUserPage(pages, search, sex, platform, sysPhone, status,member,inviterCode,userName));
    }

    @Override
    public int queryInviterCount(String inviterCode) {
        return baseMapper.queryInviterCount(inviterCode);
    }

    @Override
    public int queryUserCount(int type,String date,String platform) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
        if(date==null||date==""){
            date = simpleDateFormat.format(new Date());
        }
        return baseMapper.queryUserCount(type, date,platform);
    }

    @Override
    public Double queryPayMoney(int type) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
        String date = simpleDateFormat.format(new Date());
        return baseMapper.queryPayMoney(type, date);
    }

    @Override
    public IPage<Map<String, Object>> queryCourseOrder(Page<Map<String, Object>> iPage,int type, String date) {
        return baseMapper.queryCourseOrder(iPage,type, date);
    }

    @Override
    public int userMessage( String date, int type) {
        return baseMapper.userMessage(date, type);
    }


    @Override
    public void pushToSingle(String title, String content, String clientId) {
        GtApiConfiguration apiConfiguration = new GtApiConfiguration();
        //填写应用配置
        apiConfiguration.setAppId(commonInfoService.findOne(61).getValue());
        apiConfiguration.setAppKey(commonInfoService.findOne(60).getValue());
        apiConfiguration.setMasterSecret(commonInfoService.findOne(62).getValue());
        // 接口调用前缀，请查看文档: 接口调用规范 -> 接口前缀, 可不填写appId
        apiConfiguration.setDomain("https://restapi.getui.com/v2/");
        // 实例化ApiHelper对象，用于创建接口对象
        ApiHelper apiHelper = ApiHelper.build(apiConfiguration);
        // 创建对象，建议复用。目前有PushApi、StatisticApi、UserApi
        PushApi pushApi = apiHelper.creatApi(PushApi.class);
        //根据cid进行单推
        PushDTO<Audience> pushDTO = new PushDTO<Audience>();
        // 设置推送参数
        pushDTO.setRequestId(System.currentTimeMillis() + "");
        PushMessage pushMessage = new PushMessage();
        GTNotification notification = new GTNotification();
        pushDTO.setPushMessage(pushMessage);
        // 配置通知栏图标
        notification.setLogo("icon.png"); //配置通知栏图标，需要在客户端开发时嵌入，默认为push.png
        // 配置通知栏网络图标
        notification.setLogoUrl(commonInfoService.findOne(19).getValue() + "/logo.png");
        notification.setTitle(title);
        notification.setBody(content);
        notification.setClickType("url");
        notification.setUrl(commonInfoService.findOne(19).getValue());
        pushMessage.setNotification(notification);
        // 设置接收人信息
        Audience audience = new Audience();
        audience.addCid(clientId);
        pushDTO.setAudience(audience);
        // 进行cid单推
        ApiResult<Map<String, Map<String, String>>> apiResult = pushApi.pushToSingleByCid(pushDTO);
        if (apiResult.isSuccess()) {
            // success
            log.error("消息推送成功：" + apiResult.getData());
        } else {
            // failed
            log.error("消息推送成功失败：code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
        }
    }

    @Override
    public Result selectInviteUserList(Integer page,Integer limit,String userName,String phone){
        return Result.success().put("data",baseMapper.selectInviteUserList(new Page<>(page,limit),userName,phone));
    }

    @Override
    public Result loginByOpenId(String openId) {
        UserEntity userEntity = queryByWxId(openId);
        if (userEntity == null) {
            return Result.error(-200, "未注册！");
        }
        String token = jwtUtils.generateToken(userEntity.getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());
        map.put("user", userEntity);
        return Result.success(map);
    }

    @Override
    public Result selectUser(Long userId) {
        UserEntity userEntity = baseMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUserId, userId));
        return Result.success().put("data", userEntity);
    }

    @Override
    public void getEmailCode(String email) {
        //创建一个邮件
        SimpleMailMessage message = new SimpleMailMessage();
        // 设置发件人
        message.setFrom(nickname+'<'+sender+'>');
        // 设置收件人
        message.setTo(email);
        // 设置邮件主题
        message.setSubject("欢迎访问"+nickname);
        //生成六位随机数
        String code = RandomUtil.randomNumbers(6);
        //将验证码存入数据库，有效期为5分钟
        EmailCode emailCode = new EmailCode();
        emailCode.setCode(code);
        emailCode.setEmail(email);
        emailCode.setCreateTime(new Date());
        emailCodeDao.insert(emailCode);
        String content = "【验证码】您的验证码为：" + code + " 。 验证码五分钟内有效，逾期作废。\n\n\n" +
                "------------------------------\n\n\n" ;
        message.setText(content);
        // 发送邮件
        javaMailSender.send(message);
    }

    @Override
    public Result verifyEmailCode(String email, String code) {
        LambdaQueryWrapper<EmailCode> emailCodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        emailCodeLambdaQueryWrapper.eq(EmailCode::getEmail, email);
        emailCodeLambdaQueryWrapper.eq(EmailCode::getCode, code);
        EmailCode emailCode = emailCodeDao.selectOne(emailCodeLambdaQueryWrapper);
        if (ObjectUtils.isNotEmpty(emailCode)){
            long time = emailCode.getCreateTime().getTime();
            if (System.currentTimeMillis() - time > 5*60*1000){
                emailCodeDao.deleteById(emailCode.getId());//过期删除
                return Result.success().put("data",false);
            }else {
                emailCodeDao.deleteById(emailCode.getId());//验证后删除
                return Result.success().put("data",true);
            }
        }
        return Result.error(-200, "请先发送验证码");
    }

    @Override
    public String getUserCity(Long userId, HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            if (ip!= null && ip.length() > 15 && ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        IpInfo ipInfo = ip2regionSearcher.memorySearch(ip);
        String city = ipInfo.getCity();
        UserEntity userEntity = baseMapper.selectById(userId);
        if (ObjectUtils.isNotEmpty(userEntity.getCity())&&userEntity.getIsCity()==1){
            userEntity.setCity(city);
            baseMapper.updateById(userEntity);
            return city;
        }
        return null;
    }





}
